package com.jy.api.controller.admin;

import com.jy.api.dao.EmployeeDao;
import com.jy.api.dao.OrderDao;
import com.jy.api.dao.StoreDao;
import com.jy.api.dao.WorkShiftDao;
import com.jy.api.domain.*;
import com.jy.api.service.WorkshiftService;
import com.jy.api.timer.ScheduledTask;
import com.jy.api.util.JodaUtils;
import com.jy.api.vo.admin.workshift.WorkShiftDetailsVo;
import com.jy.api.vo.admin.workshift.WorkshiftVo;
import com.jy.api.vo.pos.WorkShift.WorkShiftVo;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.json.HTTP;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by lihu on 2017/8/31.
 */
@RequestMapping(value = "v1/admin/", produces = "application/json;charset=utf-8")
@RestController
@Slf4j
public class AdminWorkshiftController {

    @Autowired
    WorkShiftDao workShiftDao;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private MessageSource msg;

    @Autowired
    WorkshiftService workshiftService;

    @Autowired
    EmployeeDao employeeDao;

    private JdbcTemplate jdbc;
    @Autowired
    private StoreDao storeDao;

    @Autowired
    public void setJdbc(JdbcTemplate jdbc) {
        this.jdbc = jdbc;
    }

    /**
     * 获取当前班次详情
     *
     * @param id
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "workshift/{id}/details")
    public ResponseEntity getWorkshiftDetails(@PathVariable(name = "id") String id) {
        WorkShift workShift = workShiftDao.findOne(id);
        if (workShift == null) {
            return new ResponseEntity("查询失败当前交班信息不存在！", HttpStatus.BAD_REQUEST);
        }
        try {
            return ResponseEntity.ok(workshiftService.getWorkShiftDetails(workShift));
        } catch (Exception ex) {
            log.error("getWorkshiftDetails is error=>id:{}", id, ex);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);

        }
    }


    /**
     * 获取加班信息员工信息
     *
     * @param id
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "workshift/{id}/staff")
    public ResponseEntity getWorkshiftStaff(@PathVariable(name = "id") String id) {
        WorkShift workShift = workShiftDao.findOne(id);
        if (workShift == null) {
            return new ResponseEntity("查询失败当前交班信息不存在！", HttpStatus.BAD_REQUEST);
        }

        if (!workShift.isClosed()) {
            return new ResponseEntity("当前班次未交班！", HttpStatus.BAD_REQUEST);
        }

        return new ResponseEntity(getStaff(workShift.getStoreId(), workShift.getBeginTime(), workShift.getEndTime()), HttpStatus.OK);
    }

    /**
     * 拼接店员返回值
     *
     * @param storeId
     * @param start
     * @return
     */
    private List<WorkShiftVo.Staff> getStaff(String storeId, Date start, Date end) {
        List<WorkShiftVo.Staff> staff = new ArrayList<>();
        Map<String, WorkShiftVo.Staff> map = new HashMap<>();
        List<String> usernames = new ArrayList<>();

        List<Map<String, Object>> list = orderDao.getStoreCommission(storeId, start, end);
        log.info(" test info :{}", list);
        for (Map<String, Object> map1 : list) {
            String creatorId = map1.get("creatorId").toString();
            if (creatorId == null) {
                continue;
            }
            usernames.add(creatorId);
            WorkShiftVo.Staff staff1 = new WorkShiftVo.Staff(Integer.parseInt(map1.get("orderCount").toString()),
                    Double.parseDouble(map1.get("totalAmount").toString()));
            map.put(creatorId, staff1);
        }

        if (usernames.size() > 0) {
            List<Employee> employees = employeeDao.findListByStoreIdAndEnabledAndUsernameIn(storeId,
                    true, usernames);
            for (Employee employee : employees) {
                WorkShiftVo.Staff staff1 = map.get(employee.getUsername());
                if (staff1 != null) {
                    staff1.setCreatorName(employee.getName());
                    staff.add(staff1);
                }
            }
        }

        return staff;
    }


    @RequestMapping(method = RequestMethod.GET, value = "workshift/{id}/products")
    public ResponseEntity getProductsStatistics(@PathVariable(name = "id") String id,
                                                @RequestParam(name = "page", defaultValue = "0") int page,
                                                @RequestParam(name = "pageSize", defaultValue = "10") int pageSize) {
        WorkShift workShift = workShiftDao.findOne(id);
        if (workShift == null) {
            return new ResponseEntity("查询失败当前交班信息不存在！", HttpStatus.BAD_REQUEST);
        }
        return new ResponseEntity(workshiftService.getStatistics(workShift, page, pageSize), HttpStatus.OK);
    }

    /**
     * 获取交班记录并返回
     *
     * @param storeId
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "workshift/list")
    public ResponseEntity getProducts(@RequestParam(name = "storeId") String storeId,
                                      @RequestParam(name = "page", defaultValue = "0") int page,
                                      @RequestParam(name = "pageSize", defaultValue = "10") int pageSize) {
        try {
            //判断传入分页参数信息
            if (page < 0 || pageSize < 1) {
                return new ResponseEntity("分页参数错误", HttpStatus.BAD_REQUEST);
            }
            //设置分页数据
            Pageable pageable = new PageRequest(page, pageSize, Sort.Direction.DESC, "beginTime");
            Date beginTime = new Date((JodaUtils.getStartOfToday() - ScheduledTask.TRANS_DAY * 24 * 60 * 60) * 1000L);
            Page<WorkShift> workShifts = workShiftDao.findListByStoreIdAndClosedAndAddTimeGreaterThanEqual(storeId, true, beginTime, pageable);
            //初始化返回对象
            WorkshiftVo workshiftVo = new WorkshiftVo(workShifts.getTotalElements(), workShifts.getTotalPages());
            for (WorkShift workShift : workShifts) {
                WorkshiftVo.WorkShift workShift1 = new WorkshiftVo.WorkShift();
                BeanUtils.copyProperties(workShift, workShift1);
                workshiftVo.getWorkShifts().add(workShift1);
            }
            return new ResponseEntity(workshiftVo, HttpStatus.OK);
        } catch (Exception ex) {
            log.error("getProducts is error=>storeId:{}", storeId, ex);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }


    /**
     * 获取订单信息
     *
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/get/by/time")
    public ResponseEntity getAllWorkshift(@RequestParam("storeId") String storeId, @RequestParam("beginTime") String begin, @RequestParam("endTime") String end) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        Date beginTime = sdf.parse(begin);
        Date endTime = sdf.parse(end);
        List<WorkShift> workShifts = workShiftDao.findAllByTimeClosedIsTrue(storeId, beginTime, endTime);
        return ResponseEntity.ok(workShifts);
    }


    @GetMapping("get-endTime")
    public ResponseEntity getEndTime(@RequestParam("storeId") String storeId) {
        WorkShift workShift = workShiftDao.findTop1ByStoreIdAndClosedOrderByAddTimeDesc(storeId, true);
        return ResponseEntity.ok(workShift.getEndTime());
    }

    @GetMapping("deal-mobile")
    public ResponseEntity dealMobile(@RequestParam("begin") String begin, Pageable pageable) throws Exception {
        Page<Store> list = storeDao.findAllByEnabled(true, pageable);
        List<OrderStatus> orderStatuses = new ArrayList<>();
        orderStatuses.add(OrderStatus.FINISHED);
        orderStatuses.add(OrderStatus.UNFINISHED);
        SimpleDateFormat sgd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sgd.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        Date beginDate = sgd.parse(begin);
        for (Store store : list) {
            List<WorkShift> workShiftList = workShiftDao.findByStoreIdAndBeginTimeGreaterThanOrderByAddTimeAsc(store.getId(), beginDate);
            for (WorkShift workShift : workShiftList) {
                List<Order> orders;
                if (!workShift.isClosed()) {
                    orders = orderDao.findListByStoreIdAndStatusInAndEnabledAndPaymentTimeBetween(store.getId(), orderStatuses, true, workShift.getBeginTime(), new Date());
                } else {
                    orders = orderDao.findListByStoreIdAndStatusInAndEnabledAndPaymentTimeBetween(store.getId(), orderStatuses, true, workShift.getBeginTime(), workShift.getEndTime());
                }
                for (Order order : orders) {
                    order.setMobileTag(workShift.getOperatorId());
                    List<OrderItem> item = order.getItems();
                    for (OrderItem orderItem : item) {
                        orderItem.setMobileTag(workShift.getOperatorId());
                    }
                    order.setItems(item);
                }
                orderDao.save(orders);
            }
            log.info("storeId", store.getId());
        }

        return ResponseEntity.ok("操作成功");
    }


    @GetMapping("/deal/one/mobile")
    public ResponseEntity dealOneMobile(@RequestParam("begin") String begin) throws Exception {
        List<Store> store = storeDao.findAllByDeliveryEnabledIsTrue();
        List<OrderStatus> orderStatuses = new ArrayList<>();
        orderStatuses.add(OrderStatus.FINISHED);
        orderStatuses.add(OrderStatus.UNFINISHED);
        SimpleDateFormat sgd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sgd.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        Date beginDate = sgd.parse(begin);
        for (Store store1 : store) {
            List<WorkShift> workShiftList = workShiftDao.findByStoreIdAndBeginTimeGreaterThanOrderByAddTimeAsc(store1.getId(), beginDate);
            for (WorkShift workShift : workShiftList) {
                List<Order> orders;
                if (!workShift.isClosed()) {
                    orders = orderDao.findListByStoreIdAndStatusInAndEnabledAndPaymentTimeBetween(store1.getId(), orderStatuses, true, workShift.getBeginTime(), new Date());
                } else {
                    orders = orderDao.findListByStoreIdAndStatusInAndEnabledAndPaymentTimeBetween(store1.getId(), orderStatuses, true, workShift.getBeginTime(), workShift.getEndTime());
                }
                for (Order order : orders) {
                    order.setMobileTag(workShift.getOperatorId());
                    List<OrderItem> item = order.getItems();
                    for (OrderItem orderItem : item) {
                        orderItem.setMobileTag(workShift.getOperatorId());
                    }
                    order.setItems(item);
                }
                orderDao.save(orders);
            }
            log.info("storeId", store1.getId());
        }

        return ResponseEntity.ok("操作成功");
    }


    @GetMapping("get-emp")
    public ResponseEntity getEmp(@RequestParam("storeId") String storeId, @RequestParam("begin") String begin, @RequestParam("end") String end) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        Date beginTime = sdf.parse(begin);
        Date endTime = sdf.parse(end);
        List<Object[]> total = orderDao.getTotalEmpListAmount(storeId, beginTime, endTime);
        List<Map> list = new ArrayList<>();
        for (Object[] objects : total) {
            Map map = new HashMap();
            if (!objects[1].toString().equals("") || null != objects[1].toString()) {
                List<Employee> employee = employeeDao.findByStoreIdAndUsernameOrderByEnabledDesc(storeId, objects[1].toString());
                if (employee.size() > 0) {
                    map.put("name", employee.get(0).getName());
                } else {
                    map.put("name", "");
                }
                if (!employee.get(0).getGroup().getRoles().contains("ROLE_POS")) {
                    continue;
                }

            } else {
                map.put("name", "");
            }
            map.put("amount", objects[0].toString());
            map.put("mobile", objects[1].toString());
            list.add(map);
        }
        return ResponseEntity.ok(list);
    }

    /**
     * 获取当前班次详情
     *
     * @param mobile
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "workshift/choose/details")
    public ResponseEntity chooseWorkshiftDetails(@RequestParam(name = "mobile") String mobile, @RequestParam("storeId") String storeId, @RequestParam("begin") String begin, @RequestParam("end") String end) {
        try {
            return ResponseEntity.ok(workshiftService.getWorkShiftDetailsTag(mobile, storeId, begin, end));
        } catch (Exception ex) {
            log.error("getWorkshiftDetails is error=>id:{}", mobile, ex);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);

        }
    }

    /**
     * 得到分类下的商品详情
     *
     * @param mobile
     * @param storeId
     * @param typeName
     * @return
     */
    @GetMapping("get-total-itemDetails")
    public ResponseEntity getTotalSalesItemDetails(@RequestParam("begin") String begin, @RequestParam("end") String end, @RequestParam("mobile") String mobile, @RequestParam("storeId") String storeId, @RequestParam("typeName") String typeName) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        Date beginTime = sdf.parse(begin);
        Date endTime = sdf.parse(end);
        BeanPropertyRowMapper item = new BeanPropertyRowMapper<>(SalesItemDetails.class);
        item.setPrimitivesDefaultedForNullValue(true);
        List<SalesItemDetails> SalesItemDetails = jdbc.query("SELECT SUM(oi.`quantity`) AS qty , SUM(oi.`deal_price`) AS amount ,p.`name` as `name`  FROM `order_item` oi LEFT JOIN `product` p on oi.`product_id`= p.`id` WHERE `order_id` IN(SELECT `id` FROM `order` o WHERE `store_id`=?   AND o.`payment_time`> ?  AND o.`payment_time`<= ?  AND `enabled`= 1 AND o.`status` IN('UNFINISHED', 'FINISHED') AND `enabled`= 1 and o.`mobile_tag`= ? )  AND oi.`enabled`= 1  AND p.`parent_type_name`= ?    GROUP BY p.`id` ORDER BY qty DESC"
                , item, storeId, beginTime, endTime, mobile, typeName);
        return ResponseEntity.ok(SalesItemDetails);
    }


    @GetMapping(path = "workshift/{id}")
    public ResponseEntity getWorkshiftDetails(@PathVariable String id, @RequestParam(name = "page", defaultValue = "0") int page,
                                              @RequestParam(name = "pageSize", defaultValue = "10") int pageSize) {
        if (page < 0 || pageSize < 1) {
            return new ResponseEntity("分页参数错误", HttpStatus.BAD_REQUEST);
        }

        WorkShift ws = workShiftDao.findOne(id);

        if (null == ws.getBeginTime()) {
            return new ResponseEntity("该班没有开班时间", HttpStatus.BAD_REQUEST);
        }

        Pageable pageable = new PageRequest(page, pageSize, Sort.Direction.ASC, "createTime");

        Date endTime = ws.getEndTime();
        if (null == endTime) {
            endTime = new Date();
        }

        Page<Order> orders = orderDao.findListByStoreIdAndPaymentTimeBetweenAndStatusIn(ws.getStoreId(), ws.getBeginTime(), endTime, Arrays.asList(OrderStatus.UNFINISHED, OrderStatus.FINISHED), pageable);

        Page<AdminOrderVo> results = orders.map(new Converter<Order, AdminOrderVo>() {
            @Override
            public AdminOrderVo convert(Order source) {
                AdminOrderVo target = new AdminOrderVo();
                BeanUtils.copyProperties(source, target);

                target.source = msg.getMessage("order.source." + source.getSource().name(), null, Locale.CHINA);
                target.type = msg.getMessage("order.type." + source.getType().name(), null, Locale.CHINA);

                return target;
            }
        });

        return new ResponseEntity(results, HttpStatus.OK);
    }


    /**
     * 获取交班打印商品信息
     *
     * @param id
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/workshift/{id}/summary")
    public ResponseEntity getWorkShift(@PathVariable(name = "id") String id) {
        try {
            WorkShift workShift = workShiftDao.findOne(id);
            if (workShift == null) {
                return new ResponseEntity("获取失败！当前班次不存在！", HttpStatus.BAD_REQUEST);
            }
            List<SalesItem> items = workshiftService.queryClerkProdcutStatistcs(workShift.getOperatorId(), workShift.getStoreId(), workShift.getBeginTime(), new Date());
            if (null == items) {
                items = new ArrayList<>();
            }
            List<WorkShiftDetailsVo.Coupon> coupons = workshiftService.getWorkShiftCoupon(workShift,
                    workShift.getBeginTime(), workShift.getEndTime());
            Map map = new HashMap();
            map.put("types", items);
            map.put("coupons", coupons);
            return new ResponseEntity(map, HttpStatus.OK);
        } catch (Exception ex) {
            log.error("adminIndex  is error==> id{}", id, ex);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Data
    @NoArgsConstructor
    private class AdminOrderVo {
        private String id;
        private String code;
        private Date createTime;
        private Date paymentTime;
        private double amount;
        private String creatorName;
        private int count;
        private String source;
        private String type;
    }

}


